package com.hxc.common.service;
import java.io.StringWriter;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.StringJoiner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.gitlab4j.api.GitLabApi;
import org.gitlab4j.api.RepositoryFileApi;
import org.gitlab4j.api.models.RepositoryFile;
import org.springframework.stereotype.Service;
import org.json.JSONArray;
import org.json.JSONObject;
import org.apache.http.entity.StringEntity;
import org.apache.http.client.methods.HttpPost;

@Service
public class MarkDownV2Service {
  // gitlab路径
  private static final String GITLAB_URL = "http://10.160.2.29:17004";
  // gitlab v4路径
  private static final String API_URL = "http://10.160.2.29:17004/api/v4";
  // 项目id
  private static final String PROJECT_ID = "103";
  // 分支
  private static final String BRANCH_NAME = "main";
  // 需要获取文档的文件夹
  private static final String PATH = "05.异常SOP";
  // 个人令牌
  private static final String PERSONAL_ACCESS_TOKEN = "gmokyUVHoU3_d9Rwcm4B";
  // 判断图片正则
  private static final String MARKDOWN_IMAGE_PATTERN = "(!\\[[^\\]]*\\])\\(([^\\)]+)\\)";
  public void findMarkdown() throws Exception {
    HttpClient httpClient = HttpClientBuilder.create().build();

    try {
      String apiUrl = API_URL + "/projects/" + PROJECT_ID + "/repository/tree?ref=" + BRANCH_NAME + "&path=" + PATH;
      HttpGet httpGet = new HttpGet(apiUrl);

      httpGet.setHeader("Accept", "application/json");
      httpGet.setHeader("Authorization", "Bearer " + PERSONAL_ACCESS_TOKEN);

      HttpResponse response = httpClient.execute(httpGet);
      String jsonResponse = EntityUtils.toString(response.getEntity());

      System.out.println(jsonResponse);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public List<String> getGitDataFilePath() throws Exception {
    HttpClient httpClient = HttpClients.createDefault();
    List<String> filePaths = new ArrayList<>();
    // 判断是否读取完毕
    Boolean notNullFlag = true;
    Integer page = 1;

    try {
      while (notNullFlag) {
        String apiUrl = API_URL + "/projects/" + PROJECT_ID + "/repository/tree?ref=" + BRANCH_NAME + "&path=" + PATH +"&per_page=100&page="+page;

        HttpGet request = new HttpGet(apiUrl);
        request.setHeader("PRIVATE-TOKEN", PERSONAL_ACCESS_TOKEN);
        HttpResponse response = httpClient.execute(request);
        String responseBody = EntityUtils.toString(response.getEntity());
        JSONArray files = new JSONArray(responseBody);
        if (files.length() == 0) {
          notNullFlag = false;
        }
        for (int i = 0; i < files.length(); i++) {
          JSONObject file = files.getJSONObject(i);
          if ("tree".equals(file.getString("type"))) {
            filePaths.add(file.getString("name"));
          }
        }
        page++;
      }
      return filePaths;
    }catch (Exception e) {
      throw new Exception("获取markdown列表失败:"+e.getMessage());
    }
  }

  public Boolean isContainSearchKeyForContent(String searchKey,String path) {
    Boolean containFlag = false;
    String content = "";
    try {
      content = findMarkDownBypathNoWithImage(path);
    }catch (Exception e) {
      e.printStackTrace();
    }
    System.out.println(path+"内容:"+content);
    if (content.toLowerCase(Locale.ROOT).contains(searchKey.toLowerCase(Locale.ROOT))) {
      containFlag = true;
    }
    return containFlag;
  }

  public List<String> isContainSearchKeyForPaths(String searchKey,List<String> paths)
      throws Exception {
    Map<String,String> pathContentMap = findMarkDownBypathNoWithImageForAllPath(paths);
    List<String> pathList = new ArrayList<>();
    for (String path:paths) {
      String content = pathContentMap.get(path);
      if (StringUtils.isEmpty(content)) {
        continue;
      }
      if (content.toLowerCase(Locale.ROOT).contains(searchKey.toLowerCase(Locale.ROOT))) {
        pathList.add(path);
      }
    }
    return pathList;
  }

  public List<String> searchMarkDown(String searchKey) throws Exception{
    List<String> results = new ArrayList<>();
    try {
      List<String> markdownFiles = getGitDataFilePath();
      if (StringUtils.isEmpty(searchKey)) {
        results.addAll(markdownFiles);
      } else {
        for (String path:markdownFiles) {
          // 如果标题包含检索关键字加入列表
          if (path.contains(searchKey)) {
            results.add(path);
          } else {
            // 判断具体内容是否包含关键字，是则加入列表
            if (isContainSearchKeyForContent(searchKey,path)) {
              results.add(path);
            }
          }
        }
      }
      return results;
    }catch (Exception e) {
     throw new Exception(e.getMessage());
    }
  }

  public String findMarkDownBypathNoWithImage(String path) throws Exception {
    String content = "";
    HttpClient httpClient = HttpClients.createDefault();
    String apiUrl = API_URL + "/projects/" + PROJECT_ID + "/repository/tree?ref=" + BRANCH_NAME + "&path=" + PATH+"/"+URLEncoder
        .encode(path, "UTF-8");
    HttpGet request = new HttpGet(apiUrl);
    request.setHeader("PRIVATE-TOKEN", PERSONAL_ACCESS_TOKEN);
    HttpResponse response = httpClient.execute(request);
    String responseBody = EntityUtils.toString(response.getEntity());
    JSONArray files = new JSONArray(responseBody);
    for (int i = 0;i <files.length();i++) {
      JSONObject file = files.getJSONObject(i);
      if ("blob".equals(file.getString("type")) && file.getString("name").endsWith(".md")) {
        String filePath = PATH + "/"+path+"/" + file.getString("name");
        String fileContentUrl = API_URL + "/projects/" + PROJECT_ID + "/repository/files/" + URLEncoder
            .encode(filePath, "UTF-8") + "/raw?ref=" + BRANCH_NAME;

        HttpGet fileContentRequest = new HttpGet(fileContentUrl);
        fileContentRequest.setHeader("PRIVATE-TOKEN", PERSONAL_ACCESS_TOKEN);

        HttpResponse fileContentResponse = httpClient.execute(fileContentRequest);
        String fileContent = EntityUtils.toString(fileContentResponse.getEntity());

        content = fileContent;
        break;
      }

    }
    return content;
  }

  public Map<String,String> findMarkDownBypathNoWithImageForAllPath(List<String> paths) throws Exception {
    Map<String, String> contentsMap = new HashMap<>();
    HttpClient httpClient = HttpClients.createDefault();

    for (String path : paths) {
      String apiUrl = API_URL + "/projects/" + PROJECT_ID + "/repository/tree?ref=" + BRANCH_NAME + "&path=" + PATH + "/" + URLEncoder.encode(path, "UTF-8");
      HttpGet request = new HttpGet(apiUrl);
      request.setHeader("PRIVATE-TOKEN", PERSONAL_ACCESS_TOKEN);
      HttpResponse response = httpClient.execute(request);
      String responseBody = EntityUtils.toString(response.getEntity());
      JSONArray files = new JSONArray(responseBody);
      for (int i = 0; i < files.length(); i++) {
        JSONObject file = files.getJSONObject(i);
        if ("blob".equals(file.getString("type")) && file.getString("name").endsWith(".md")) {
          String filePath = file.getString("name");
          String fileContentUrl = API_URL + "/projects/" + PROJECT_ID + "/repository/files/" + URLEncoder.encode(PATH + "/" + path + "/" + filePath, "UTF-8") + "/raw?ref=" + BRANCH_NAME;
          HttpGet fileContentRequest = new HttpGet(fileContentUrl);
          fileContentRequest.setHeader("PRIVATE-TOKEN", PERSONAL_ACCESS_TOKEN);
          HttpResponse fileContentResponse = httpClient.execute(fileContentRequest);
          String fileContent = EntityUtils.toString(fileContentResponse.getEntity());
          contentsMap.put(path, fileContent); // 将传入的 path 作为 key，文件内容作为 value，添加到Map中
        }
      }
    }

    return contentsMap;
  }

  public String findMarkDownBypathWithImage(String path) throws Exception {
    String markDownNoImageContent = findMarkDownBypathNoWithImage(path);
    Pattern pattern = Pattern.compile(MARKDOWN_IMAGE_PATTERN);
    Matcher matcher = pattern.matcher(markDownNoImageContent);
    StringBuffer sb = new StringBuffer();
    while (matcher.find()) {
      String originalImageTag = matcher.group(0);
      String altText = matcher.group(1);
      String imagePath = matcher.group(2);
      try {
        String base64 = getImageBase64(imagePath,path);
        String transformedImageTag = "![Image](" + base64 + ")";
        matcher.appendReplacement(sb, transformedImageTag);
      }catch (Exception e) {
        e.printStackTrace();
      }
    }
    matcher.appendTail(sb);
    return sb.toString();
  }

  public String getImageBase64(String imagePath,String markDownPath) throws Exception {
    String filePath = PATH+"/"+markDownPath +"/" +imagePath;
    // 创建 GitLab API 实例
    GitLabApi gitLabApi = new GitLabApi(GITLAB_URL, PERSONAL_ACCESS_TOKEN);
    String base64 = "";
    String fileType = fileType(imagePath);
    // 获取文件内容
    try {
      RepositoryFileApi repositoryFileApi = gitLabApi.getRepositoryFileApi();
      RepositoryFile file = repositoryFileApi.getFile(PROJECT_ID, filePath, BRANCH_NAME);

      // 将文件内容转换为 Base64
      String base64Content = file.getContent();
      base64 = fileType+base64Content;
      System.out.println(base64Content);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return base64;
  }

  public String fileType(String fileName) throws Exception {
    fileName = fileName.toLowerCase(Locale.ROOT);
    if (fileName.endsWith("png")) {
      return "data:image/png;base64,";
    } else if (fileName.endsWith("jpg") || fileName.endsWith("jpeg")) {
      return "data:image/jpeg;base64,";
    }
    return "";
  }

}
